#include <botan/hash.h>
#include <utils/functions.h>

#include <botan/secmem.h>
namespace utils {
CipherAlgorithm createAlgos(const std::string& str) {
	if(str == "Kuznyechik/CBC")
		return utils::CipherAlgorithm::Kuznyechik_CBC;
	if(str == "GOST-28147-89/CBC")
		return utils::CipherAlgorithm::Magma_CBC;
	if(str == "AES-256/CBC")
		return utils::CipherAlgorithm::AES_256_CBC;
	return utils::CipherAlgorithm::Kuznyechik_CBC;
}

std::string createStringFromAlgos(CipherAlgorithm algos) {
	switch (algos) {
		case utils::CipherAlgorithm::Kuznyechik_CBC:
			return "Kuznyechik/CBC";
		case utils::CipherAlgorithm::Magma_CBC:
			return "GOST-28147-89/CBC";
		case utils::CipherAlgorithm::AES_256_CBC:
			return "AES-256/CBC";
	}
	return "Kuznyechik/CBC";
}

std::vector<std::string> split(const std::string &str, const std::string& delimeter) {
	std::vector<std::string> r;

	std::string::size_type start = 0;
	std::string::size_type stop = str.find(delimeter, start);
	while(stop != std::string::npos) {
		r.push_back(str.substr(start, stop - start));

		start = stop + delimeter.size();
		stop = str.find(delimeter, start);
	}
	if(!str.substr(start).empty())
		r.push_back(str.substr(start));

	return r;
}

Botan::secure_vector<std::uint8_t> generateSymmetricKeyFromPassword(const std::string& password, size_t key_length) {
	std::unique_ptr hash(Botan::HashFunction::create("Streebog-512"));
	if (!hash) {
		throw std::runtime_error("Streebog-512 is not available");
	}
	hash->update(reinterpret_cast<const std::uint8_t*>(password.data()), password.length());

	Botan::secure_vector<std::uint8_t> hash_result = hash->final();

	if (hash_result.size() > key_length) {
		hash_result.resize(key_length);
	} else if (hash_result.size() < key_length) {
		throw std::runtime_error("Generated hash is too short for the required key length");
	}

	return hash_result;
}
}